package com.huluobo.a2308douyindemo.mvvm

import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.blankj.utilcode.util.ToastUtils
import com.huluobo.a2308douyindemo.net.MessageEvent
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.lang.reflect.ParameterizedType

/**
 *  Created by LC on 2025/10/22.
 */
abstract class BaseFragment<VDB : ViewDataBinding, VM : BaseViewModel> : Fragment() {
    //获取当前类的实现类的2个具体类型VDB和VM
    //type是是一个数组
    private val type by lazy { (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments }

    //通过反射的形式获取布局,来给binding赋值
    protected val binding by lazy {
        //获取泛型中的第一个,强转成页面类
        val clazz = type[0] as Class<VDB>

        //如果在activity中获取布局,使用的是
//        binding = ActivityViewBindingBinding.inflate(layoutInflater)
        //通过反射的方式拿到inflate方法
        val method = clazz.getMethod("inflate", LayoutInflater::class.java)
        method.invoke(null, layoutInflater) as VDB
    }

    //通过反射的形式给ViewModel赋值
    protected val vm by lazy {
        //获取泛型第二位的值,强转成对应的ViewModel
        val clazz = type[1] as Class<VM>
        //实例化具体的ViewModel,使用Fragment的ViewModel的时候,不能传this,需要传递他的Activity
        ViewModelProvider(requireActivity())[clazz]
    }

    //通用的错误方法
    //由于所有请求失败是通用的,所以在产生错误的时候,通过通用的方法来展示错误信息
    open fun onError(t: Throwable) {
        ToastUtils.showLong(t.message)
        Log.e("TagA", "onError:${t.message}")
        t.printStackTrace()
    }

    //当页面创建时
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return binding.root
    }

    //当页面创建后
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        vm.onFailed.observe(requireActivity(), ::onError)
        initView()
        initData()
        //EventBus注册,使所有Activity都可以发送和接受EventBus
        EventBus.getDefault().register(this)
    }

    abstract fun initData()

    abstract fun initView()

    //EventBus的接收方法,需要发送的地方直接使用EventBusPost即可
    @Subscribe(threadMode = ThreadMode.MAIN)
    open fun onEvent(messageEvent: MessageEvent) {

    }

    //不带参数的跳转activity
    open fun <T> startAct(activity: Class<T>) {
        val intent = Intent(requireActivity(), activity)
        startActivity(intent)
    }


    companion object {
        const val INTENT_PARAM = "intent_param"
    }

    //带参数的跳转activity
    open fun <T> startAct(activity: Class<T>, params: Bundle?) {
        val intent = Intent(requireActivity(), activity)
        intent.putExtra(INTENT_PARAM, params)
        startActivity(intent)
    }
}